using System;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

/// <summary>
/// IEForumBrowser derived from ApplicationContext supports message loop
/// </summary>
public class IEForumBrowser : System.Windows.Forms.ApplicationContext 
{
    AutoResetEvent resultEvent;

    string _userName, _password;
    string _forumUrl;
    string _newthreadUrl;
    int caseId = -1;

    string htmlResult;
    string htmlCookieTable;
    string htmlInputTable;
    string htmlScriptTable;

    int loginCount;
    int htmlCount;
    int navigationCounter;
    ScriptCallback scriptCallback;

    public WebBrowser ieBrowser;
    Form form;
    Thread thrd;

    public string humanverify;
    public string recaptcha_image;

    public string HtmlResult
    {
        get { return htmlResult; }
    }

    public int NavigationCounter
    {
        get { return navigationCounter; }
    }

    public string HtmlCookieTable
    {
        get { return "Cookies:" + htmlCookieTable; }
    }

    public string HtmlInputTable
    {
        get { return "Input elements:" + htmlInputTable; }
    }

    public string HtmlScriptTable
    {
        get { return "Script variables:" + htmlScriptTable; }
    }

    /// <summary>
    /// class constructor 
    /// </summary>
    /// <param name="visible">whether or not the form and the WebBrowser control are visiable</param>
    /// <param name="userName">client user name</param>
    /// <param name="password">client password</param>
    /// <param name="resultEvent">functionality to keep the main thread waiting</param>
    public IEForumBrowser(bool visible, string forumUrl, string newthreadUrl, string userName, string password, AutoResetEvent resultEvent)
    {
        this._userName = userName;
        this._password = password;
        this._forumUrl = forumUrl;
        this._newthreadUrl = newthreadUrl;
        this.resultEvent = resultEvent;
        htmlResult = null;
        htmlCount = 0;
        //loginCount = 0;
        thrd = new Thread(new ThreadStart(
            delegate {
                Init(visible);
                System.Windows.Forms.Application.Run(this); 
            }));
        // set thread to STA state before starting
        thrd.SetApartmentState(ApartmentState.STA);
        thrd.Start();
    }

    /// <summary>
    /// class constructor 
    /// </summary>
    /// <param name="visible">whether or not the form and the WebBrowser control are visiable</param>
    /// <param name="userName">client user name</param>
    /// <param name="password">client password</param>
    /// <param name="resultEvent">functionality to keep the main thread waiting</param>
    public IEForumBrowser(string forumUrl, string userName, string password, string newthreadUrl, string title, string message, AutoResetEvent resultEvent, bool visible)
    {
        this._userName = userName;
        this._password = password;
        this._forumUrl = forumUrl;
        //this._newthreadUrl = newthreadUrl;
        this.resultEvent = resultEvent;
        htmlResult = null;
        htmlCount = 0;
        //loginCount = 0;
        thrd = new Thread(new ThreadStart(
            delegate
            {
                PostNewThread_vBulletin(newthreadUrl, title, message);
                System.Windows.Forms.Application.Run(this);
            }));
        // set thread to STA state before starting
        thrd.SetApartmentState(ApartmentState.STA);
        thrd.Start();
    }

    /// <summary>
    /// class constructor 
    /// </summary>
    /// <param name="visible">whether or not the form and the WebBrowser control are visiable</param>
    /// <param name="userName">client user name</param>
    /// <param name="password">client password</param>
    /// <param name="resultEvent">functionality to keep the main thread waiting</param>
    public IEForumBrowser(string forumUrl, string userName, string password, string newthreadUrl, AutoResetEvent resultEvent, bool visible)
    {
        this._userName = userName;
        this._password = password;
        this._forumUrl = forumUrl;
        //this._newthreadUrl = newthreadUrl;
        this.resultEvent = resultEvent;
        htmlResult = null;
        htmlCount = 0;
        //loginCount = 0;
        thrd = new Thread(new ThreadStart(
            delegate
            {
                GetReCaptcha_vBulletin(newthreadUrl);
                System.Windows.Forms.Application.Run(this);
            }));
        // set thread to STA state before starting
        thrd.SetApartmentState(ApartmentState.STA);
        thrd.Start();
    }

    // initialize the WebBrowser and the form
    private void Init(bool visible)
    {
        scriptCallback = new ScriptCallback(this);

        // create a WebBrowser control
        ieBrowser = new WebBrowser();
        // set the location of script callback functions
        ieBrowser.ObjectForScripting = scriptCallback;
        // set WebBrowser event handls
        ieBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(IEBrowser_DocumentCompleted);
        ieBrowser.Navigating += new WebBrowserNavigatingEventHandler(IEBrowser_Navigating);
        if (visible)
        {
            form = new System.Windows.Forms.Form();
            ieBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
            form.Controls.Add(ieBrowser);
            form.Visible = true;
        }

        loginCount = 0;
        // initialise the navigation counter
        navigationCounter = 0;
        caseId = 0; //login
        ieBrowser.Navigate(_forumUrl);
    }

    //private CookieContainer _cookies;
    //public CookieContainer GetCookieContainer()
    //{
    //    CookieContainer container = new CookieContainer();

    //    foreach (string cookie in ieBrowser.Document.Cookie.Split(';'))
    //    {
    //        string name = cookie.Split('=')[0];
    //        string value = cookie.Substring(name.Length + 1);
    //        string path = "/";
    //        string domain = ".google.com"; //change to your domain name
    //        container.Add(new Cookie(name.Trim(), value.Trim(), path, domain));
    //    }
        
    //    return container;
    //}

    public void PostNewThread_vBulletin(string newThreadUrl, string title, string message)
    {
        scriptCallback = new ScriptCallback(this);

        // create a WebBrowser control
        ieBrowser = new WebBrowser();
        // set the location of script callback functions
        ieBrowser.ObjectForScripting = scriptCallback;
        // set WebBrowser event handls
        ieBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(IEBrowser_DocumentCompleted);
        ieBrowser.Navigating += new WebBrowserNavigatingEventHandler(IEBrowser_Navigating);

        bool visible = true;
        if (visible)
        {
            form = new System.Windows.Forms.Form();
            ieBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
            form.StartPosition = FormStartPosition.CenterScreen;
            form.WindowState = FormWindowState.Maximized;
            form.Controls.Add(ieBrowser);
            form.Visible = true;
        }

        loginCount = 0;
        // initialise the navigation counter
        navigationCounter = 0;
        //========================================================================================================
        //Step 1: Login
        caseId = 0;
        //check is login already?

        ieBrowser.Navigate(_forumUrl);
        //Wait complete
        while (ieBrowser.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        bool isLogin = false;
        if (ieBrowser.Document != null)
        {
            //HtmlElement htmlElem = ieBrowser.Document.GetElementById("nav_back");
            //HtmlElementCollection elems = htmlElem.GetElementsByTagName("a");
            //foreach (HtmlElement elem in elems)
            //{
            //    if (elem.GetAttribute("href") == "usercp.php"){
            //        isLogin = true;
            //        break;
            //    }
            //}
            foreach (string cookie in ieBrowser.Document.Cookie.Split(';'))
            {
                string name = cookie.Split('=')[0];
                if (name.Contains("sessionhash"))
                {
                    isLogin = true;
                    break;
                }
                //string value = cookie.Substring(name.Length + 1);

            }
            //if (ieBrowser.DocumentText.Contains("usercp.php"))
            //{
            //    isLogin = true;
            //}
        }

        if (!isLogin)
        {
            //Fill username & pass
            ieBrowser.Document.GetElementById("navbar_username").InnerText = _userName;
            ieBrowser.Document.GetElementById("navbar_password").InnerText = _password;

            //Submit Login
            //ieBrowser.Document.Forms[0].InvokeMember("submit");
            HtmlElementCollection elems = ieBrowser.Document.GetElementsByTagName("input");
            foreach (HtmlElement elem in elems)
            {
                if (elem.GetAttribute("value") == "Log in")
                {
                    elem.InvokeMember("click");
                    waitTillLoad(ieBrowser);
                    break;
                }
            }
        }

        //Check login status
        foreach (string cookie in ieBrowser.Document.Cookie.Split(';'))
        {
            string name = cookie.Split('=')[0];
            if (!name.Contains("sessionhash"))
            {
                return;
            }
        }

        int count = 3;
        while ((count--) > 0)
        {
            //========================================================================================================
            //Step 2: Post a new thread
            //Thread.Sleep(2000);
            caseId = 1; //Start New thread
            ieBrowser.Navigate(newThreadUrl);
            //Wait complete
            while (ieBrowser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
            //Load success
            if (ieBrowser.Url.AbsoluteUri == newThreadUrl)
            {
                count = -1;
                HtmlDocument doc = ieBrowser.Document;
                //Get humanverify[hash]
                HtmlElementCollection elems = doc.GetElementsByTagName("input");
                foreach (HtmlElement elem in elems)
                {
                    if (elem.GetAttribute("name") == "humanverify[hash]")
                    {
                        humanverify = elem.GetAttribute("value");
                        break;
                    }
                }

                //Get image
                elems = doc.GetElementsByTagName("div");
                foreach (HtmlElement elem in elems)
                {
                    if (elem.GetAttribute("id") == "recaptcha_image")
                    {
                        recaptcha_image = elem.GetElementsByTagName("img")[0].GetAttribute("src");
                        break;
                    }
                }

                //========================================================================================================
                //Step 3: Fill content
                //Thread.Sleep(2000);
                caseId = 2;
                if (ieBrowser.Document != null)
                {
                    //HtmlElementCollection elems = ieBrowser.Document.GetElementsByTagName("input");
                    elems = ieBrowser.Document.GetElementsByTagName("input");
                    foreach (HtmlElement elem in elems)
                    {
                        if (elem.GetAttribute("name") == "subject")
                            elem.SetAttribute("value", title);
                    }
                    //try
                    //{
                        //elems = ieBrowser.Document.GetElementsByTagName("html");
                        //elems = elems.GetElementsByName("body");
                        //elems[0].InnerText = message;
                        ieBrowser.Document.GetElementById("vB_Editor_001_textarea").InnerText = message;
                    //}
                    //catch
                    //{
                    //    ieBrowser.Document.GetElementById("vB_Editor_001").InnerText = message;

                    //}
                    //ieBrowser.Document.GetElementById("vB_Editor_001_textarea").AttachEventHandler("change", handler);
                }

                resultEvent.Set();
            }

            
        }

        
        
        ////========================================================================================================
        ////Step 4: clikc button Preview post
        //Thread.Sleep(2000);
        //caseId = 3;
        //if (ieBrowser.Document != null)
        //{
        //    elems = ieBrowser.Document.GetElementsByTagName("input");
        //    foreach (HtmlElement elem in elems)
        //    {
        //        if (elem.GetAttribute("name") == "preview")
        //        {
        //            elem.InvokeMember("click");
        //            WaitTillLoad(ieBrowser);
        //            break;
        //        }
        //    }
        //}
        ////Wait complete
        //while (ieBrowser.ReadyState != WebBrowserReadyState.Complete)
        //{
        //    Application.DoEvents();
        //}

        string returnUrl = ieBrowser.Url.AbsoluteUri;
        //ieBrowser.Document.InvokeScript("setTimeout", new object[] { string.Format("window.external.getHtmlResult({0})", navigationCounter), 10 });
    }

    public void GetReCaptcha_vBulletin(string newThreadUrl)
    {
        scriptCallback = new ScriptCallback(this);

        // create a WebBrowser control
        ieBrowser = new WebBrowser();
        // set the location of script callback functions
        ieBrowser.ObjectForScripting = scriptCallback;
        // set WebBrowser event handls
        ieBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(IEBrowser_DocumentCompleted);
        ieBrowser.Navigating += new WebBrowserNavigatingEventHandler(IEBrowser_Navigating);

        bool visible = true;
        if (visible)
        {
            form = new System.Windows.Forms.Form();
            ieBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
            form.StartPosition = FormStartPosition.CenterScreen;
            form.WindowState = FormWindowState.Maximized;
            form.Controls.Add(ieBrowser);
            form.Visible = true;
        }

        loginCount = 0;
        // initialise the navigation counter
        navigationCounter = 0;
        //========================================================================================================
        //Step 1: Login
        caseId = 0;
        //check is login already?
        
        ieBrowser.Navigate(_forumUrl);
        //Wait complete
        while (ieBrowser.ReadyState != WebBrowserReadyState.Complete)
        {
            Application.DoEvents();
        }

        bool isLogin = false;
        if (ieBrowser.Document != null)
        {
            //HtmlElement htmlElem = ieBrowser.Document.GetElementById("nav_back");
            //HtmlElementCollection elems = htmlElem.GetElementsByTagName("a");
            //foreach (HtmlElement elem in elems)
            //{
            //    if (elem.GetAttribute("href") == "usercp.php"){
            //        isLogin = true;
            //        break;
            //    }
            //}
            if (ieBrowser.DocumentText.Contains("usercp.php"))
            {
                isLogin = true;
            }
        }

        if (!isLogin)
        {
            //Fill username & pass
            ieBrowser.Document.GetElementById("navbar_username").InnerText = _userName;
            ieBrowser.Document.GetElementById("navbar_password").InnerText = _password;

            //Submit Login
            //ieBrowser.Document.Forms[0].InvokeMember("submit");
            HtmlElementCollection elems = ieBrowser.Document.GetElementsByTagName("input");
            foreach (HtmlElement elem in elems)
            {
                if (elem.GetAttribute("value") == "Log in")
                {
                    elem.InvokeMember("click");
                    waitTillLoad(ieBrowser);
                    break;
                }
            }
        }
        
        int count = 3;
        while ((count--) > 0)
        {
            //========================================================================================================
            //Step 2: Post a new thread
            //Thread.Sleep(2000);
            caseId = 1; //Start New thread
            ieBrowser.Navigate(newThreadUrl);
            //Wait complete
            while (ieBrowser.ReadyState != WebBrowserReadyState.Complete)
            {
                Application.DoEvents();
            }
            if (ieBrowser.Url.AbsoluteUri == newThreadUrl)
            {
                count = -1;
                HtmlDocument doc = ieBrowser.Document;
                //Get humanverify[hash]
                HtmlElementCollection elems = doc.GetElementsByTagName("input");
                foreach (HtmlElement elem in elems)
                {
                    if (elem.GetAttribute("name") == "humanverify[hash]")
                    {
                        humanverify = elem.GetAttribute("value");
                        break;
                    }
                }

                //Get image
                elems = doc.GetElementsByTagName("div");
                foreach (HtmlElement elem in elems)
                {
                    if (elem.GetAttribute("id") == "recaptcha_image")
                    {
                        recaptcha_image = elem.GetElementsByTagName("img")[0].GetAttribute("src");
                        break;
                    }
                }

                resultEvent.Set();
            }
        }


        ////========================================================================================================
        ////Step 3: Fill content
        ////Thread.Sleep(2000);
        //caseId = 2;
        //if (ieBrowser.Document != null)
        //{
        //    //HtmlElementCollection elems = ieBrowser.Document.GetElementsByTagName("input");
        //    elems = ieBrowser.Document.GetElementsByTagName("input");
        //    foreach (HtmlElement elem in elems)
        //    {
        //        if (elem.GetAttribute("name") == "subject")
        //            elem.SetAttribute("value", title);
        //    }
        //    ieBrowser.Document.GetElementById("vB_Editor_001_textarea").InnerText = message;
        //    //ieBrowser.Document.GetElementById("vB_Editor_001_textarea").AttachEventHandler("change", handler);
        //}

        ////========================================================================================================
        ////Step 4: clikc button Preview post
        //Thread.Sleep(2000);
        //caseId = 3;
        //if (ieBrowser.Document != null)
        //{
        //    elems = ieBrowser.Document.GetElementsByTagName("input");
        //    foreach (HtmlElement elem in elems)
        //    {
        //        if (elem.GetAttribute("name") == "preview")
        //        {
        //            elem.InvokeMember("click");
        //            WaitTillLoad(ieBrowser);
        //            break;
        //        }
        //    }
        //}
        ////Wait complete
        //while (ieBrowser.ReadyState != WebBrowserReadyState.Complete)
        //{
        //    Application.DoEvents();
        //}

        //string returnUrl = ieBrowser.Url.AbsoluteUri;
        //ieBrowser.Document.InvokeScript("setTimeout", new object[] { string.Format("window.external.getHtmlResult({0})", navigationCounter), 10 });
    }

    //public void GetReCaptcha(string requestUrl)
    //{
    //    thrd = new Thread(new ThreadStart(
    //        delegate
    //        {
    //            caseId = 1;//open new thread
    //            ieBrowser.Navigate(requestUrl);
    //            System.Windows.Forms.Application.Run(this);
    //        }));
    //    // set thread to STA state before starting
    //    thrd.SetApartmentState(ApartmentState.STA);
    //    thrd.Start();
    //}

    //public void PostNewThread(string forumUrl, string newthreadUrl, string title, string message)
    //{
    //    AutoResetEvent resultEvent = new AutoResetEvent(false);
    //    thrd = new Thread(new ThreadStart(
    //        delegate
    //        {
    //            caseId = -1;//open new thread
    //            ieBrowser.Navigate(forumUrl);
    //        }));
    //    // set thread to STA state before starting
    //    thrd.SetApartmentState(ApartmentState.STA);
    //    thrd.Start();
    //    // wait for the third thread getting result and setting result event
    //    EventWaitHandle.WaitAll(new AutoResetEvent[] { resultEvent });
    //}

    // dipose the WebBrowser control and the form and its controls
    protected override void Dispose(bool disposing)
    {
        if (thrd != null)
        {
            thrd.Abort();
            thrd = null;
            return;
        }

        System.Runtime.InteropServices.Marshal.Release(ieBrowser.Handle);
        ieBrowser.Dispose();
        if (form != null) form.Dispose();
        base.Dispose(disposing);
    }

    // Navigating event handle
    void IEBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
    {
        // navigation count increases by one
        navigationCounter++;
        // write url into the form's caption
        if (form != null) form.Text = e.Url.ToString();
    }

    public void DoLogin(HtmlDocument doc)
    {
        string url = doc.Url.AbsoluteUri;
        string formText = form.Text;
        //if (doc.Title.Equals("Sign In") && loginCount++ < 3)
        //if (!string.IsNullOrEmpty(doc.Title) && loginCount++ < 1)
        if (url == _forumUrl && loginCount++ < 1)
        //if (caseId == 0)
        {
            // set email address and password, and try to login three times
            try
            {
                doc.GetElementById("navbar_username").InnerText = _userName;
                doc.GetElementById("navbar_password").InnerText = _password;
                //Thread.Sleep(20);
                doc.Forms[0].InvokeMember("submit");
                //caseId = 2;
            }
            catch { }
            //doc.InvokeScript("setTimeout", new object[] { "document.f1.submit()", 20 });
        }
        else
        {
              // resultEvent.Set();
              // request jscript to call c# callback function with a parameter of navigation counter
              doc.InvokeScript("setTimeout", new object[] { string.Format("window.external.getHtmlResult({0})", navigationCounter), 10 });
        }
    }

    private int reCaptchaCount = 0;
    private void GetReCaptcha(HtmlDocument doc)
    {
        string url = doc.Url.AbsoluteUri;
        if (!string.IsNullOrEmpty(doc.Title) && reCaptchaCount++ < 1)
        {
            // set email address and password, and try to login three times
            try
            {
                //Get humanverify[hash]
                HtmlElementCollection elems = doc.GetElementsByTagName("input");
                foreach (HtmlElement elem in elems)
                {
                    if (elem.GetAttribute("name") == "humanverify[hash]")
                    {
                        humanverify = elem.GetAttribute("value");
                        break;
                    }
                }

                //Get image
                elems = doc.GetElementsByTagName("div");
                foreach (HtmlElement elem in elems)
                {
                    if (elem.GetAttribute("id") == "recaptcha_image")
                    {
                        recaptcha_image = elem.GetElementsByTagName("img")[0].GetAttribute("src");
                        break;
                    }
                }
                
            }
            catch { }
            //doc.InvokeScript("setTimeout", new object[] { "document.f1.submit()", 20 });
        }
        else
        {
            //    resultEvent.Set();
            //    // request jscript to call c# callback function with a parameter of navigation counter
            doc.InvokeScript("setTimeout", new object[] { string.Format("window.external.getHtmlResult({0})", navigationCounter), 10 });
        }
    }

    /// <summary>
    /// References: 
    /// 1. http://stackoverflow.com/questions/6434687/waiting-for-ajax-load-using-web-browser-control
    /// 2. http://codingform.blogspot.com/2009/08/c-webbrowser-control-synchronization.html
    /// </summary>
    /// <param name="webBrControl"></param>
    public void waitTillLoad(WebBrowser webBrControl) {
        WebBrowserReadyState loadStatus;
        //wait till beginning of loading next page 
        int waittime = 100000;
        int counter = 0;
        while (true)
        {
            loadStatus = webBrControl.ReadyState;

            Application.DoEvents();

            if ((counter > waittime) || (loadStatus == WebBrowserReadyState.Uninitialized) || (loadStatus == WebBrowserReadyState.Loading) || (loadStatus == WebBrowserReadyState.Interactive))
            {
                break;
            }
            counter++;
        }

        //wait till the page get loaded.
        counter = 0;
        while (true)
        {
            loadStatus = webBrControl.ReadyState;
            Application.DoEvents();

            if (loadStatus == WebBrowserReadyState.Complete && webBrControl.IsBusy != true)
            {
                break;
            }
            counter++;
        }
    }

    // DocumentCompleted event handle
    void IEBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        HtmlDocument doc = ((WebBrowser)sender).Document;

        //switch (caseId)
        //{
        //    case 0:
        //        DoLogin(doc);
        //        break;
        //    case 1:
        //        //ieBrowser.Navigate("http://www.final4ever.com/newthread.php?do=postthread&f=25");
        //        //ieBrowser.Navigate("http://www.mastiya.com/newthread.php?do=newthread&f=27");
        //        GetReCaptcha(doc);
        //        break;
        //    case 2:

        //        break;
        //};

        switch (caseId)
        {
            case 0:
                break;
            case 1:
                break;
            case 2:
                break;
            case 3:
                break;
        };
        
    }


    /// <summary>
    /// class to hold the functions called by script codes in the WebBrowser control
    /// </summary>
    [System.Runtime.InteropServices.ComVisible(true)]
    public class ScriptCallback
    {
        IEForumBrowser owner;
        static string scriptPattern;

        public ScriptCallback(IEForumBrowser owner)
        {
            this.owner = owner;

            // read JScript.js only once
            if (scriptPattern != null) return;
            StreamReader rd = File.OpenText(System.AppDomain.CurrentDomain.BaseDirectory + "JScript.js");
            scriptPattern = rd.ReadToEnd();
            rd.Close();
        }

        // callback function to get the content of page in the WebBrowser control 
        public void getHtmlResult(int count)
        {
            // unequal means the content is not stable
            if (owner.navigationCounter != count) return;

            // get HTML content
            owner.htmlResult = owner.ieBrowser.DocumentText;
            string filePath = "C:\\result" + (owner.htmlCount++).ToString() + ".html";
            if (File.Exists(filePath))
            {
                FileStream fs = File.Create(filePath);
                Byte[] info = new UTF8Encoding(true).GetBytes(owner.htmlResult);
                fs.Write(info, 0, info.Length);
                fs.Close();
            }
            else
            {
                TextWriter tw = new StreamWriter(filePath);
                tw.Write(owner.htmlResult);
                tw.Close();
            }
            owner.resultEvent.Set();
            //return;
            //==============================================================================
            HtmlDocument doc = owner.ieBrowser.Document;
            
            //if (doc.Cookie != null)
            //{
            //    // get cookies
            //    owner.htmlCookieTable = "<table border=1 cellspacing=0 cellpadding=2><tr><th>Name</th><th>Value</th><tr>";
            //    foreach (string cookie in Regex.Split(doc.Cookie, @";\s*"))
            //    {
            //        string[] arr = cookie.Split(new char[] { '=' }, 2);
            //        owner.htmlCookieTable += string.Format("<td>{0}</td><td>{1}</td></tr>", arr[0], (arr.Length == 2) ? arr[1] : "&nbsp;");
            //    }
            //    owner.htmlCookieTable += "</table><p />";
            //}

            //HtmlElementCollection inputs = doc.GetElementsByTagName("INPUT");
            //if (inputs.Count != 0)
            //{
            //    // get ids, names, values and types of input elements
            //    owner.htmlInputTable = "<table border=1 cellspacing=0 cellpadding=2><tr><th>Id</th><th>Name</th><th>Value</th><th>Type</th><tr>";
            //    foreach (HtmlElement input in inputs)
            //    {
            //        owner.htmlInputTable += string.Format("<td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td></tr>", input.GetAttribute("Id"), input.GetAttribute("Name"), input.GetAttribute("Value"), input.GetAttribute("Type"));
            //    }
            //    owner.htmlInputTable += "</table><p />";
            //    owner.htmlInputTable = owner.htmlInputTable.Replace("<td></td>", "<td>&nbsp;</td>");
            //}

            //HtmlElementCollection scripts = doc.GetElementsByTagName("SCRIPT");
            //if (scripts.Count != 0)
            //{
            //    string vars = string.Empty;
            //    foreach (HtmlElement script in scripts)
            //    {
            //        if (script.InnerHtml == null) continue;

            //        foreach (string name in getVariableNames(script.InnerHtml).Split(new char[] { ';' }))
            //        {
            //            if (name.Trim().Length == 0) continue;
            //            if (vars.Contains("\"" + name + "\"")) continue;

            //            // one row of the script variable table - <tr>getValue([script variable name]</tr> - getValue() is a script function in JScript.js
            //            vars += string.Format("+\"<tr>\"+getValue(\"{0}\")+\"</tr>\"", name);
            //        }
            //    }
            //    if (vars != "")
            //    {
            //        scriptPattern = scriptPattern.Replace("{0}", vars.Substring(1));
            //        // request script to send back the names, values and types of script variables
            //        doc.InvokeScript("setTimeout", new object[] { scriptPattern, 10 });
            //    }
            //}
            //else
            //{
            //    // set resultEvent to let main thread continue
            //    owner.resultEvent.Set();
            //}
        }

        // get script variable names from the InnerHtml of script tag
        string getVariableNames(string InnerHtml)
        {
            // remove fuction definitions
            int n;
            Regex r = new Regex(@"\{|\}");
            while (true)
            {
                Match m1 = Regex.Match(InnerHtml, @"function\s+[^\(]+\(|new\s+function\s*\(|function\s*\(");
                if (!m1.Success) break;

                int nestCount = 0;
                n = m1.Groups[0].Index;
                do
                {
                    Match m2 = r.Match(InnerHtml, n + 1);
                    n = m2.Groups[0].Index;
                    try
                    {
                        nestCount += (m2.Groups[0].Value[0] == '{') ? 1 : -1;
                    }
                    catch
                    {
                        return "";
                    }
                } while (nestCount != 0);

                InnerHtml = InnerHtml.Remove(m1.Groups[0].Index, n - m1.Groups[0].Index + 1);
            }

            // remove "if (...)"
            r = new Regex(@"\(|\)");
            while (true)
            {
                Match m1 = Regex.Match(InnerHtml, @"if\s*\(");
                if (!m1.Success) break;

                int nestCount = 0;
                n = m1.Groups[0].Index;
                do
                {
                    Match m2 = r.Match(InnerHtml, n + 1);
                    n = m2.Groups[0].Index;
                    nestCount += (m2.Groups[0].Value[0] == '(') ? 1 : -1;
                } while (nestCount != 0);

                InnerHtml = InnerHtml.Remove(m1.Groups[0].Index, n - m1.Groups[0].Index + 1);
            }

            InnerHtml = Regex.Replace(InnerHtml, @"\W+try\s*\{|\}\s*catch\([^\)]+\)\s*\{|\Welse\W", ";");
            InnerHtml = Regex.Replace(InnerHtml, @"<[^>]+>[^<]*<[^>]+>|<!--[^>]+>", "");
            InnerHtml = Regex.Replace(InnerHtml, @"\+*=[^;\}]+[;\}]|\{|\}", ";");

            string variables = string.Empty;
            //Match m = Regex.Match(InnerHtml, @"(var\s|;+|^|\{+)\s*(\S+?)\s*(=[\s\S]+?[;$]|;|\}|$)");
            r = new Regex(@"(var\s|;+|^)\s*(\S+?)\s*(;+|$)");
            n = 0;
            while (true)
            {
                Match m = r.Match(InnerHtml, n);
                if (!m.Success) break;

                variables += ";" + m.Groups[2].Value;
                n = m.Index + m.Length - 1;
            }

            // remove function calling
            variables = Regex.Replace(variables, @";[^;]+\([^\(;]+", "", RegexOptions.RightToLeft);

            variables = Regex.Replace(variables, @"^\W*;+\s*|\s*;+\W*$", "");
            variables = Regex.Replace(variables, @";{2,}", ";");
            variables = variables.Replace('"', '\'');

            return variables;
        }

        // callback function to set the names, values and types of script variables
        // parameter vars conains the names, values and types of script variables
        public void getScriptResult(string vars) {

            // set script table
            owner.htmlScriptTable = "<table border=1 cellspacing=0 cellpadding=2><tr><th>Name</th><th>Value</th><th>Type</th><tr>" + vars + "</table><p />";
            owner.htmlScriptTable = owner.htmlScriptTable.Replace("<td></td>", "<td>&nbsp;</td>");

            // set resultEvent to let main thread continue
            owner.resultEvent.Set();
        }
    }
}

//public class IEBrowser_vBulletin : IEForumBrowser
//{
//    public IEBrowser_vBulletin(bool visible, string userName, string password, AutoResetEvent resultEvent)
//    {
//        int i = 0;
//    }
//}

